#include<iostream>
#include<fstream>
#include<string.h>
#include<hash_map>
#include<sstream>
#include"Logger.h"
#include"ConfigService.h"

using namespace std;

namespace configService{

	string Config::CONFIGFILENAME = "config.ini";
	Config* Config::instance = NULL;

	/** 
	  * Returns a pointer to the Config Instance
	  * @return Config* Config
	  */
	Config* Config::getConfig(){

	
		if(Config::instance == NULL)
		{
			Config::instance = new Config();
			instance->properties = hash_map<string,string>();
			Config::instance->configfile_open();		
		}

		return Config::instance;
	};

	/**
	  * returns the value to the ke
	  */
	string Config::getProperty(string pKey)
	{		
		return this->properties[pKey];
	};

	/**
	  * Opens the config file for reading
	  * @throws -1 When opening fails or an error occurs
	  *
	  */
	void Config::configfile_open(){
		Config::configfile.open(Config::CONFIGFILENAME);	
		if(!Config::configfile)
		{		
			throw -1;
		}

		char line[255];
		do
		{
			configfile.getline(line,255);
			string str = line;
			if(str[0] != ';')
			{
				int position = str.find("=");

				if(position==string::npos){
					throw -1;
				}

				string key = str.substr(0,position);
				string value = str.substr(position+1,str.length()-(position+1));
				this->properties[key] = value;
			}
		}while(!configfile.eof());
	};

	/* Closes the config file
	 * Deletes the properties from the memory
	 *
	 */
	void Config::configfile_close(){
		Config::configfile.close();
	};


	/* void destructor - calls configfile_close()
	 *
	 */
	Config::~Config(){
		Config::configfile_close();
	};


	/* void constructor - constructs a new Config Service instance
	 * Because the Config Service is based on singleton pattern it is private
	 */
	Config::Config(){

	};

	string Config::toString(){
		
		stringstream ss;
		ss << "Configuration:{";
		hash_map<string,string>::iterator iter;
		for(iter=this->properties.begin();iter!=this->properties.end();iter++)
		{
			ss << iter->first << "=" << iter->second << ";";
		}
		ss << "}";
		return ss.str();
	}
}